/*
 * Copyright (C) 2012 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package cc.angis.xiugallery.image.ui;

import java.io.File;
import java.io.IOException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

import android.annotation.SuppressLint;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnCompletionListener;
import android.media.MediaRecorder;
import android.media.MediaRecorder.AudioSource;
import android.media.MediaRecorder.OutputFormat;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentStatePagerAdapter;
import android.support.v4.view.ViewPager;
import android.util.DisplayMetrics;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.MeasureSpec;
import android.view.View.OnClickListener;
import android.view.View.OnLongClickListener;
import android.view.View.OnTouchListener;
import android.view.ViewGroup;
import android.view.WindowManager.LayoutParams;
import android.view.animation.Animation;
import android.view.animation.Transformation;
import android.widget.Button;
import android.widget.EditText;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;
import cc.angis.xiugallery.R;
import cc.angis.xiugallery.ShareActivity;
import cc.angis.xiugallery.common.GlobalConst;
import cc.angis.xiugallery.db.ImageDescDBHelper;
import cc.angis.xiugallery.db.TableConstants;
import cc.angis.xiugallery.image.util.ImageCache;
import cc.angis.xiugallery.image.util.ImageDetailLoader;
import cc.angis.xiugallery.image.util.ImageResizer;
import cc.angis.xiugallery.image.util.ImageWorker;
import cc.angis.xiugallery.provider.FavouriteImageProvider;
import cc.angis.xiugallery.provider.GalleryImageProvider;
import cc.angis.xiugallery.provider.ISourceProvider;

import com.actionbarsherlock.app.ActionBar;
import com.actionbarsherlock.app.SherlockFragmentActivity;
import com.actionbarsherlock.view.Menu;
import com.actionbarsherlock.view.MenuItem;

public class ImageDetailActivity extends SherlockFragmentActivity implements
		OnClickListener {
	private static final String IMAGE_CACHE_DIR = "images";
	public static final String EXTRA_IMAGE = "extra_image";

	private ImagePagerAdapter mAdapter;
	private ImageResizer mImageWorker;
	private ViewPager mPager;
	private Button mButton;

	private ActionBar mActionbar;

	private MediaRecorder mRecorder;

	private String mVoicePath;

	private RelativeLayout totalLayout;
	
	private Button inputVoiceButton;
	
	private Button inputTextButton;
	
	private EditText inputEditText;
	
	private Button saveButton;

	@SuppressLint("NewApi")
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.image_detail_pager);
		initLayout();
		initListener();
		
		mActionbar = this.getSupportActionBar();
		// Enable "up" navigation on ActionBar icon and hide title text
		mActionbar.setDisplayHomeAsUpEnabled(true);
		// Fetch screen height and width, to use as our max size when loading
		// images as this
		// activity runs full screen
		final DisplayMetrics displaymetrics = new DisplayMetrics();
		getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);
		final int height = displaymetrics.heightPixels - mActionbar.getHeight() - 
				getResources().getDimensionPixelSize(R.dimen.view_desc_min_height) - 
				getResources().getDimensionPixelSize(R.dimen.view_desc_input_height);
		final int width = displaymetrics.widthPixels;
//		final int longest = height > width ? height : width;

		// The ImageWorker takes care of loading images into our ImageView
		// children asynchronously
		mImageWorker = new ImageDetailLoader(this, width,height);
		String id = getIntent().getStringExtra(GlobalConst.INTENT_BUCKET_ID);
		int type = getIntent().getIntExtra(GlobalConst.INTENT_GROUP_TYPE, 0);
		ISourceProvider provider;
		switch (type) {
		case 0:
			provider = new GalleryImageProvider(this, id);
			break;
		case 1:
			provider = new FavouriteImageProvider(this, id);
		default:
			provider = new FavouriteImageProvider(this, id);
			break;
		}
		provider.initSource();
		mImageWorker.setAdapter(provider);
		mImageWorker.setImageCache(ImageCache.findOrCreateCache(this,
				IMAGE_CACHE_DIR));
		mImageWorker.setImageFadeIn(false);

		// Set up ViewPager and backing adapter
		mAdapter = new ImagePagerAdapter(getSupportFragmentManager(),
				mImageWorker.getAdapter().getSize());
		mPager = (ViewPager) findViewById(R.id.pager);
		mPager.setAdapter(mAdapter);
		mPager.setPageMargin((int) getResources().getDimension(
				R.dimen.image_detail_pager_margin));

		// Set up activity to go full screen
		getWindow().addFlags(LayoutParams.FLAG_FULLSCREEN);

		// Set the current item based on the extra passed in to this activity
		final int extraCurrentItem = getIntent().getIntExtra(
				GlobalConst.INTENT_CUR_IMAGE_SEQUENCE, -1);
		if (extraCurrentItem != -1) {
			mPager.setCurrentItem(extraCurrentItem);
		}
	}
	
	private void initLayout(){
		totalLayout = (RelativeLayout) findViewById(R.id.totallayout);
		inputVoiceButton = (Button) findViewById(R.id.inputvoice);
		inputTextButton = (Button) findViewById(R.id.inputtext);
		inputEditText = (EditText) findViewById(R.id.desctextinput);
		saveButton = (Button) findViewById(R.id.savedesc);
		mButton = (Button) findViewById(R.id.voicebutton);
	}
	
	private void initListener(){
		inputVoiceButton.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				inputVoiceButton.setVisibility(View.GONE);	
				inputTextButton.setVisibility(View.VISIBLE);
				inputEditText.setVisibility(View.GONE);	
				saveButton.setVisibility(View.GONE);	
				mButton.setVisibility(View.VISIBLE);
			}
		});
		
		inputTextButton.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				inputVoiceButton.setVisibility(View.VISIBLE);	
				inputTextButton.setVisibility(View.GONE);
				inputEditText.setVisibility(View.VISIBLE);	
				saveButton.setVisibility(View.VISIBLE);	
				mButton.setVisibility(View.GONE);
			}
		});
		
		saveButton.setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View v) {
				if(inputEditText.getText() ==null || inputEditText.getText().toString().trim().equals("")){
					Toast.makeText(getApplicationContext(), R.string.toast_nocontent, Toast.LENGTH_SHORT).show();
					return;
				} 
				ImageDescDBHelper dbHelper = new ImageDescDBHelper(getApplicationContext(), TableConstants.TABLE_IMAGE_DESC);
				try{
					if (dbHelper.isExist(TableConstants.ImageDescColumn.IMGID, TableConstants.ImageDescColumn.TYPE, 
							mImageWorker.getAdapter().getImageItem(mPager.getCurrentItem()).toString(), "1")){
						AlertDialog.Builder builder = new AlertDialog.Builder(ImageDetailActivity.this);
						builder.setTitle(R.string.replace_text_title)
						.setPositiveButton(R.string.yes, new DialogInterface.OnClickListener() {
							@Override
							public void onClick(DialogInterface dialog, int which) {
								ImageDescDBHelper dbHelper = new ImageDescDBHelper(getApplicationContext(), TableConstants.TABLE_IMAGE_DESC);
								try{
								dbHelper.update(Long.parseLong(mImageWorker.getAdapter()
										.getImageItem(mPager.getCurrentItem())
										.toString()), 1, inputEditText.getText().toString().trim(), null);
								setText(inputEditText.getText().toString().trim());
								} catch(Exception e){
									e.printStackTrace();
								} finally{
									dbHelper.closeDB();
								}
							}
						}).setNegativeButton(R.string.no, new DialogInterface.OnClickListener() {
							@Override
							public void onClick(DialogInterface dialog, int which) {
							}
						}).show();
					} else {
						dbHelper.insert(Long.parseLong(mImageWorker.getAdapter()
								.getImageItem(mPager.getCurrentItem())
								.toString()), 1, inputEditText.getText().toString().trim(), null);
						setText(inputEditText.getText().toString().trim());
					}
				} catch(Exception e){
					e.printStackTrace();
				} finally{
					dbHelper.closeDB();
				}
					
			}
		});
		
		mButton.setOnTouchListener(new OnTouchListener() {

			@Override
			public boolean onTouch(View v, MotionEvent event) {
				switch (event.getAction()) {
				case MotionEvent.ACTION_DOWN:
					mRecorder = new MediaRecorder();
					mRecorder.setAudioSource(AudioSource.MIC);
					// 设置音源,这里是来自麦克风,虽然有VOICE_CALL,但经真机测试,不行
					mRecorder.setOutputFormat(OutputFormat.THREE_GPP);
					// 输出格式
					mRecorder
							.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
					String voiceId = UUID.randomUUID().toString();
					createDir(GlobalConst.PATH_VOICE);
					mVoicePath = GlobalConst.PATH_VOICE + voiceId + ".3gpp";
					mRecorder.setOutputFile(mVoicePath);
					try {
						mRecorder.prepare();
						// 做些准备工作
						mRecorder.start();
						// 开始
					} catch (Exception e) {
						Toast.makeText(ImageDetailActivity.this, "录音失败，请重试",
								Toast.LENGTH_SHORT).show();
					}
					break;
				case MotionEvent.ACTION_UP:
					// TODO Auto-generated method stub
					ImageDescDBHelper dbHelper = new ImageDescDBHelper(
							ImageDetailActivity.this,
							TableConstants.TABLE_IMAGE_DESC);
					try {
						mRecorder.stop();
						// 停止
						mRecorder.release();
						if (dbHelper.isExist(TableConstants.ImageDescColumn.IMGID, TableConstants.ImageDescColumn.TYPE, 
								mImageWorker.getAdapter().getImageItem(mPager.getCurrentItem()).toString(), "0")){
							AlertDialog.Builder builder = new AlertDialog.Builder(ImageDetailActivity.this);
							builder.setTitle(R.string.replace_voice_title)
							.setPositiveButton(R.string.yes, new DialogInterface.OnClickListener() {
								@Override
								public void onClick(DialogInterface dialog, int which) {
									ImageDescDBHelper dbHelper = new ImageDescDBHelper(
											ImageDetailActivity.this,
											TableConstants.TABLE_IMAGE_DESC);
									try{
									dbHelper.update(
											Long.parseLong(mImageWorker.getAdapter()
													.getImageItem(mPager.getCurrentItem())
													.toString()), 0, null, mVoicePath);
									setVoice(mVoicePath);
									} catch(Exception e){
										e.printStackTrace();
									} finally{
										dbHelper.closeDB();
									}
									
								}
							}).setNegativeButton(R.string.no, new DialogInterface.OnClickListener() {
								@Override
								public void onClick(DialogInterface dialog, int which) {
								}
							}).show();
						} else {
							dbHelper.insert(
									Long.parseLong(mImageWorker.getAdapter()
											.getImageItem(mPager.getCurrentItem())
											.toString()), 0, null, mVoicePath);
							setVoice(mVoicePath);
							Toast.makeText(ImageDetailActivity.this, "录音成功",
									Toast.LENGTH_SHORT).show();
						}
					} catch (Exception e) {
						Toast.makeText(ImageDetailActivity.this, "录音失败，请重试",
								Toast.LENGTH_SHORT).show();
					} finally {
						dbHelper.closeDB();
					}
					break;
				default:
					break;
				}
				return false;
			}
		});
	}

	private void createDir(String dirPath) {
		try {
			String paths[] = dirPath.split("/");
			String lPath = "/";
			for (int i = 0; i < paths.length; i++) {
				if (!paths[i].trim().equals("")) {
					lPath = lPath + paths[i] + "/";
					File lFile = new File(lPath);
					if (!lFile.exists()) {
						lFile.mkdir();
					}
				}
			}
		} catch (Exception e) {
		}
	}
	
	private void setText(String text){
		View view = null;
		for(int i=0;i<mPager.getChildCount();i++){
			View tview =	((ViewGroup)mPager.getChildAt(i)).getChildAt(0);
			if(tview.getTag().toString().equals(mImageWorker.getAdapter().getImageItem(mPager.getCurrentItem()).toString()))
				view = tview;
		}
		TextView imgTextView = (TextView) view.findViewById(R.id.desc_text);
		imgTextView.setVisibility(View.VISIBLE);
		imgTextView.setText(text);
		mAdapter.notifyDataSetChanged();
	}
	
	private MediaPlayer mMediaPlayer;
	private void setVoice(final String path){
		View view = null;
		for(int i=0;i<mPager.getChildCount();i++){
			View tview =	((ViewGroup)mPager.getChildAt(i)).getChildAt(0);
			if(tview.getTag().toString().equals(mImageWorker.getAdapter().getImageItem(mPager.getCurrentItem()).toString()))
				view = tview;
		}
		final Button mVoicePlayButton = (Button) view.findViewById(R.id.voiceplaybutton);
		mVoicePlayButton.setVisibility(View.VISIBLE);
		mVoicePlayButton.setContentDescription(path);
	}

	/**
	 * Called by the ViewPager child fragments to load images via the one
	 * ImageWorker
	 * 
	 * @return
	 */
	public ImageWorker getImageWorker() {
		return mImageWorker;
	}

	/**
	 * The main adapter that backs the ViewPager. A subclass of
	 * FragmentStatePagerAdapter as there could be a large number of items in
	 * the ViewPager and we don't want to retain them all in memory at once but
	 * create/destroy them on the fly.
	 */
	private class ImagePagerAdapter extends FragmentStatePagerAdapter {
		private final int mSize;
		
		public ImagePagerAdapter(FragmentManager fm, int size) {
			super(fm);
			mSize = size;
		}

		@Override
		public int getCount() {
			return mSize;
		}

		@Override
		public Fragment getItem(int position) {
			
			ImageDetailFragment lFragment = ImageDetailFragment.newInstance(mImageWorker.getAdapter()
					.getImageItem(position).toString());
			
			return lFragment;
		}
		
		

		@Override
		public void destroyItem(ViewGroup container, int position, Object object) {
			final ImageDetailFragment fragment = (ImageDetailFragment) object;
			// As the item gets destroyed we try and cancel any existing work.
			fragment.cancelWork();
			super.destroyItem(container, position, object);
		}
		
	}

	/**
	 * Set on the ImageView in the ViewPager children fragments, to
	 * enable/disable low profile mode when the ImageView is touched.
	 */
	@SuppressLint("NewApi")
	@Override
	public void onClick(View v) {
//		mButton.setVisibility(View.GONE);
//		if (mActionbar.isShowing()) {
//			mActionbar.hide();
//		} else
//			mActionbar.show();
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		getSupportMenuInflater().inflate(R.menu.menu4, menu);
		return super.onCreateOptionsMenu(menu);
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		switch (item.getItemId()) {
		case android.R.id.home:
			finish();
			break;
		case R.id.share_button:
			Intent i = new Intent(this, ShareActivity.class);
			i.putExtra(GlobalConst.INTENT_IMAGE_ID, Long.parseLong(mImageWorker.getAdapter()
					.getImageItem(mPager.getCurrentItem())
					.toString()));
			startActivity(i);
			break;
		default:
			break;
		}
		return super.onOptionsItemSelected(item);
	}

	public static Animation expand(final View v, int initHeight, int targetHeight) {
		try {
			Method m = v.getClass().getDeclaredMethod("onMeasure", int.class,
					int.class);
			m.setAccessible(true);
			m.invoke(v,
					MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED),
					MeasureSpec.makeMeasureSpec(
							((View) v.getParent()).getMeasuredWidth(),
							MeasureSpec.AT_MOST));
		} catch (Exception e) {
			e.printStackTrace();
		}
		final int initialHeight = initHeight;
		final int tHeight = targetHeight;
		v.getLayoutParams().height = targetHeight;
		Animation a = new Animation() {
			@Override
			protected void applyTransformation(float interpolatedTime,
					Transformation t) {
				int newHeight = 0;
				if (initialHeight < tHeight) {
					newHeight = (int) (initialHeight * interpolatedTime);
				} else {
					newHeight = (int) (initialHeight * (1 - interpolatedTime));
				}
				v.getLayoutParams().height = newHeight;
				v.requestLayout();
			}

			@Override
			public boolean willChangeBounds() {
				return true;
			}
		};
		a.setDuration(300);
		return a;
	}

	@Override
	public void onDestroy() {
		if(mMediaPlayer != null){
			mMediaPlayer.release();
         }
		super.onDestroy();
	}
}
